/*
 * Data Mashup Canonical Model. A canonical model for representing data mashups
 * Copyright (C) 2011 Carlos Rodriguez
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package eu.ict_omelette.mashup.canonicalmodel;

import java.io.Serializable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 *
 * @author Carlos Rodriguez
 */
public class Component implements Serializable, Cloneable {
    private String id;
    private String name;
    private String type;
    private Boolean isEmbedding;

    private List<InputPort> inPorts;
    private List<OutputPort> outPorts;
    private List<OutputAttribute> outAttributes;
    private List<InputParameter> inputParams;
    private List<Component> embeddedComps;


    public Component(){
        inPorts = new LinkedList();
        outPorts = new LinkedList();
        inputParams = new LinkedList();
        embeddedComps = new LinkedList();
        outAttributes = new LinkedList();
    }

    /**
     * @return the id
     */
    public String getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the type
     */
    public String getType() {
        return type;
    }

    /**
     * @param type the type to set
     */
    public void setType(String type) {
        this.type = type;
    }

    /**
     * @return the isEmbedding
     */
    public Boolean getIsEmbedding() {
        return isEmbedding;
    }

    /**
     * @param isEmbedding the isEmbedding to set
     */
    public void setIsEmbedding(Boolean isEmbedding) {
        this.isEmbedding = isEmbedding;
    }

    public void addInputPort(InputPort inPort){
        this.inPorts.add(inPort);
    }

    public void removeInputPort(InputPort inPort){
        this.inPorts.remove(inPort);
    }

    public InputPort getInputPort(String name){
        Iterator<InputPort> it = inPorts.iterator();

        InputPort inPort = null;
        while(it.hasNext()){
            InputPort aux = it.next();

            if(aux.getName().equals(name)){
                inPort = aux;
                break;
            }
        }

        return inPort;
    }

    public Iterator<InputPort> getInputPorts(){
        return inPorts.iterator();
    }

    public void addOutputPort(OutputPort outPort){
        this.outPorts.add(outPort);
    }

    public void removeOutputPort(OutputPort outPort){
        this.outPorts.remove(outPort);
    }

    public OutputPort getOutputPort(String name){
        Iterator<OutputPort> it = outPorts.iterator();

        OutputPort outPort = null;
        while(it.hasNext()){
            OutputPort aux = it.next();

            if(outPort.getName().equals(name)){
                outPort = aux;
                break;
            }
        }

        return outPort;
    }

    public Iterator<OutputPort> getOutputPorts(){
        return outPorts.iterator();
    }

    public void addOutputAttribute(OutputAttribute outAttribute){
        outAttributes.add(outAttribute);
    }

    public void removeOutputAttribute(OutputAttribute outAttribute){
        outAttributes.remove(outAttribute);
    }

    public OutputAttribute getOutputAttribute(String name){
        Iterator<OutputAttribute> it = outAttributes.iterator();

        OutputAttribute outAttribute = null;
        while(it.hasNext()){
            OutputAttribute aux = it.next();

            if(aux.getName().equals(name)){
                outAttribute = aux;
                break;
            }
        }

        return outAttribute;
    }

    public Iterator<OutputAttribute> getOutputAttributes(){
        return outAttributes.iterator();
    }

    public void addInputParameter(InputParameter inputParam){
        inputParams.add(inputParam);
    }

    public void removeInputParameter(InputParameter inputParam){
        inputParams.remove(inputParam);
    }

    public InputParameter getInputParameter(String name){
        Iterator<InputParameter> it = inputParams.iterator();

        InputParameter inputParam = null;

        while(it.hasNext()){
            InputParameter aux = it.next();

            if(inputParam.getName().equals(name)){
                inputParam = aux;
                break;
            }
        }

        return inputParam;
    }

    public Iterator<InputParameter> getInputParameters(){
        return inputParams.iterator();
    }

    public void addEmbeddedComponent(Component comp){
        embeddedComps.add(comp);
    }

    public void removeEmbeddedComponent(Component comp){
        embeddedComps.remove(comp);
    }

    public Component getEmbeddedComponent(String id){
        Iterator<Component> it = embeddedComps.iterator();

        Component comp = null;

        while(it.hasNext()){
            Component aux = it.next();

            if(aux.getId().equals(id)){
                comp = aux;
                break;
            }

        }

        return comp;
    }

    public Iterator<Component> getEmbeddedComponents(){
        return embeddedComps.iterator();
    }

    @Override
    public Component clone(){
        Component cloneComp = new Component();

        cloneComp.setId(this.getId());
        cloneComp.setIsEmbedding(this.getIsEmbedding());
        cloneComp.setName(this.getName());
        cloneComp.setType(this.getType());

        Iterator<InputPort> itIp = this.getInputPorts();
        while(itIp.hasNext()){
            InputPort ip = itIp.next();
            cloneComp.addInputPort((InputPort)ip.clone());
            
        }

        Iterator<Component> itEmb= this.getEmbeddedComponents();
        while(itEmb.hasNext()){
            Component c= itEmb.next();
            cloneComp.addEmbeddedComponent(c.clone());
        }

        Iterator<InputParameter> itInPar = this.getInputParameters();
        while(itInPar.hasNext()){
            InputParameter ip = itInPar.next();
            cloneComp.addInputParameter((InputParameter)ip.clone());
        }

        Iterator<OutputAttribute> itOa = this.getOutputAttributes();
        while(itOa.hasNext()){
            OutputAttribute oa = itOa.next();
            cloneComp.addOutputAttribute((OutputAttribute)oa.clone());
        }

        Iterator<OutputPort> itOp = this.getOutputPorts();
        while(itOp.hasNext()){
            OutputPort op = itOp.next();
            cloneComp.addOutputPort((OutputPort)op.clone());
        }
        
        return cloneComp;
    }
}
